class Node {
  constructor(element) {
    // 保存元素
    this.element = element;
    // 指向下一个节点
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
    this.length = 0;
  }

  // *1.append:追加方法
  append(element) {
    // 1.创建一个节点
    const newNode = new Node(element);

    // 2.追加
    // 2.1没有节点的情况
    if (this.length === 0) {
      this.head = newNode;
    }
    // 2.2有节点的情况
    else {
      let current = this.head;
      while (current.next) {
        current = current.next;
      }
      current.next = newNode;
    }

    this.length++;
  }

  // *2.insert:插入方法
  insert(position, element) {
    // 1.越界判断
    if (position < 0 || position > this.length) return false;

    // 2.创建节点
    const newNode = new Node(element);

    // 3.插入判断
    // 第一个节点
    if (position === 0) {
      newNode.next = this.head;
      this.head = newNode;
    }
    // 非第一个节点
    else {
      let index = 0;
      let current = this.head;
      let previous = null;
      while (index++ < position) {
        previous = current;
        current = current.next;
      }
      previous.next = newNode;
      newNode.next = current;
    }

    this.length++;
    return true;
  }

  // *3.get:获取对应位置的元素
  get(position) {
    // 1.越界判断
    if (position < 0 || position > this.length - 1) return null;

    // 2.查询对应位置的元素
    let index = 0;
    let current = this.head;
    while (index++ < position) {
      current = current.next;
    }

    return current.element;
  }

  // *4.indexOf:返回元素在链表中的索引,如果没有返回-1
  indexOf(element) {
    let current = this.head;
    let index = 0;
    while (current) {
      if (current.element === element) {
        return index;
      }
      index++;
      current = current.next;
    }

    return -1;
  }

  // *5.update:修改某个位置的元素
  update(position, element) {
    const result = this.removeAt(position);
    this.insert(position, element);
    return result;
  }

  // *6.removeAt:删除某个位置的元素
  removeAt(position) {
    // 1.越界判断
    if (position < 0 || position > this.length - 1) return null;

    // 2.删除元素
    let current = this.head;
    let previous = null;
    let index = 0;

    if (position === 0) {
      this.head = current.next;
    } else {
      while (index++ < position) {
        previous = current;
        current = current.next;
      }
      previous.next = current.next;
    }

    this.length--;
    return current.element;
  }

  // *7.remove:从链表中移除一项
  remove(element) {
    // 1.获取元素位置
    const index = this.indexOf(element);
    if (index === -1) return;
    return this.removeAt(index);
  }

  isEmpty() {
    return this.length === 0;
  }

  size() {
    return this.length;
  }
}
